home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 80 / CD Actual 80 Julio-Agosto 2003.iso / Linux / LinuxGazette / lg / issue14 / misc / supermount-0.4c-for-2.0.diff < prev    next >
Encoding:
Text File  |  2002-08-14  |  69.3 KB  |  2,457 lines

  1. *** linux/Documentation/filesystems/supermount.txt.~1~    Thu May 30 15:49:07 1996
  2. --- linux/Documentation/filesystems/supermount.txt    Thu May 30 15:22:30 1996
  3. ***************
  4. *** 0 ****
  5. --- 1,141 ----
  6. + Supermount README
  7. + =================
  8. + For supermount v0.4
  9. + Supermount is a pseudo-filesystem which manages filesystems on
  10. + removable media like floppy disks and CD-ROMs.  It aims to make
  11. + management of removable media as easy as it is under DOS.
  12. + With supermount, you can change the disk in the drive whenever you
  13. + want (with the obvious exception that you shouldn't do it when the
  14. + filesystem is actively in use).  You don't need to "cd" out of the
  15. + directory first, and you don't need to tell the kernel what you're
  16. + doing --- supermount will detect the media change automatically.
  17. + Supermount will automatically detect whether the media you are
  18. + mounting is read-write or readonly, and if you mount a write-protected
  19. + disk, then the subfs will be mounted as a readonly filesystem.
  20. + Supermount detects when you have finished activity on the subfs, and
  21. + will flush all buffers to the disk before completing the operation.
  22. + So, if you copy a file onto a supermounted floppy disk, the data will
  23. + all be written to disk before the "cp" command finishes.  When the
  24. + command does complete, it will be safe to remove the disk.
  25. + It is worth while defining what I mean by "activity" here.  The subfs
  26. + is active if there are any processes running which have a handle on a
  27. + non-directory inode on the subfs, or which have a file open on the
  28. + subfs (even if only for reading).  There is one important case which
  29. + does NOT count as activity: if you "cd" to a directory or a
  30. + subdirectory under the supermount mount point, then that reference
  31. + does not make the subfs active, and you can safely remove the disk.
  32. + Yes, that's right.  You can "cd /floppy; ls" and get a listing of a
  33. + dos floppy.  Remove the disk, insert a new one, and "ls" will now list
  34. + the new contents.  Remove the disk altogether, and "ls" will give you
  35. + an I/O error.  Put in a new disk, and "ls" starts working again.  It
  36. + is NOT an error to remove a supermounted disk which is acting as the
  37. + current working directory for one or more processes!
  38. + The Superfilesystem and Subfilesystem concepts
  39. + ----------------------------------------------
  40. + Normally, when you mount a filesystem, you create a direct connection
  41. + between a mount point in the directory tree and a filesystem on a
  42. + block device.  Supermount adds an extra layer in between; with
  43. + supermount, you explicitly mount the pseudo-filesystem (the
  44. + "superfilesystem") on the mount point, and supermount then
  45. + automatically mounts the real filesystem (the "subfilesystem") on the
  46. + block device when needed.
  47. + Running supermount
  48. + ------------------
  49. + To run supermount, compile and install a kernel with the supermount
  50. + patches and select "Y" to the question
  51. +     Dynamic mounting of removable media?
  52. + when you run "make config".  You set up a supermount filesystem with
  53. + the normal mount command, using the syntax:
  54. +     mount -o <superfs-options>,--,<subfs-options> / <mount-point>
  55. + Notice that I specified "/" instead of giving a block device to
  56. + supermount.  This is because the supermount filesystem is NOT
  57. + connected to a block device; rather, supermount is responsible for
  58. + connecting a separate filesystem to the block device.  You specify
  59. + this by providing the <superfs-options> field, where the following
  60. + options are currently recognised:
  61. + * subfs=<filesystem-type>        [default is "msdos"]
  62. +     Specify the subfilesystem type.  "msdos" and "iso9660" have
  63. + been tested, but any block-device filesystem should work with one
  64. + important restriction: the filesystem must NOT try to write to the
  65. + device when you unmount it.  This is because supermount doesn't know
  66. + in advance when it will have to unmount the subfs, so it doesn't try
  67. + to do so until it detects that the media has been changed.  By this
  68. + time it is too late to write to the device!
  69. +     If you mount supermount as a readonly filesystem ("mount -r"
  70. + or "mount -o ro"), then you won't have this problem.  Otherwise, you
  71. + will not be able to use the ext2fs or minix filesystems with
  72. + supermount.  This will hopefully be addressed in a future release of
  73. + supermount.
  74. + * dev=<block-device>            [default is "/dev/fd0"]
  75. +     Specify the block device on which the subfs is to be mounted.
  76. + * debug
  77. +     Enable debugging code in the supermount filesystem, if
  78. + the debug option was enabled at compile time.  By default, debugging
  79. + code is compiled into the kernel but is disabled until a debug mount
  80. + option is seen.
  81. + * '--'
  82. +     All options after the option string '--' will be passed
  83. + directly to the subfilesystem when it gets mounted.
  84. + Here is an example of supermount options, taken directly out of my
  85. + current /etc/fstab:
  86. + / /floppy    supermount    --,gid=51,conv=binary    0 0
  87. + / /cd        supermount    ro,fs=iso9660,dev=/dev/hdd,--,conv=binary 0 0
  88. + This tells supermount to manage a msdos filesystem on /dev/fd0 mounted
  89. + at /floppy (msdos and /dev/fd0 are defaults for supermount), with the
  90. + msdos filesystem getting the options "gid=51,conv=binary".  My cdrom
  91. + on /dev/hdd is similarly mounted on /cd.
  92. + Enjoy supermount.  I hope you find it useful --- I certainly find it
  93. + extremely convenient.  Send any comments, bug-fixes or bug-reports,
  94. + suggestions and success stories to sct@dcs.ed.ac.uk.  Flames to
  95. + /dev/null, please!
  96. + Cheers,
  97. +  Stephen.
  98. + --
  99. + Stephen Tweedie <sct@dcs.ed.ac.uk>
  100. + Department of Computer Science, Edinburgh University, Scotland.
  101. + ================================================================
  102. + Changes for v0.4:
  103. + Performance tuning only.  Read-only operations like "find" should now
  104. + be MUCH faster.
  105. + Changes for v0.3:
  106. + Fixed supermount_create bug; now returns a properly attached
  107. + superinode.
  108. + Changes for v0.2:
  109. + Improved device invalidation code, so CD-ROMs work now.
  110. *** linux/fs/Config.in.~1~    Thu May 30 15:49:07 1996
  111. --- linux/fs/Config.in    Thu May 30 15:22:31 1996
  112. ***************
  113. *** 6,11 ****
  114. --- 6,12 ----
  115.   
  116.   bool     'Quota support' CONFIG_QUOTA
  117.   bool     'Mandatory lock support' CONFIG_LOCK_MANDATORY
  118. + bool     'Supermount removable media support' CONFIG_SUPERMOUNT
  119.   tristate 'Minix fs support' CONFIG_MINIX_FS
  120.   tristate 'Extended fs support' CONFIG_EXT_FS
  121.   tristate 'Second extended fs support' CONFIG_EXT2_FS
  122. *** linux/fs/Makefile.~1~    Thu May 30 15:49:07 1996
  123. --- linux/fs/Makefile    Thu May 30 15:23:05 1996
  124. ***************
  125. *** 17,23 ****
  126.   
  127.   MOD_LIST_NAME := FS_MODULES
  128.   ALL_SUB_DIRS = minix ext ext2 fat msdos vfat proc isofs nfs xiafs umsdos \
  129. !         hpfs sysv smbfs ncpfs ufs affs
  130.   
  131.   ifeq ($(CONFIG_QUOTA),y)
  132.   O_OBJS += dquot.o
  133. --- 17,23 ----
  134.   
  135.   MOD_LIST_NAME := FS_MODULES
  136.   ALL_SUB_DIRS = minix ext ext2 fat msdos vfat proc isofs nfs xiafs umsdos \
  137. !         hpfs sysv smbfs ncpfs ufs affs supermount
  138.   
  139.   ifeq ($(CONFIG_QUOTA),y)
  140.   O_OBJS += dquot.o
  141. ***************
  142. *** 139,144 ****
  143. --- 139,152 ----
  144.     ifeq ($(CONFIG_HPFS_FS),m)
  145.     MOD_SUB_DIRS += hpfs
  146.     endif
  147. + endif
  148. + ifeq ($(CONFIG_SUPERMOUNT),y)
  149. + SUB_DIRS += supermount
  150. + #else
  151. + #  ifeq ($(CONFIG_SUPERMOUNT),m)
  152. + #  MOD_SUB_DIRS += supermount
  153. + #  endif
  154.   endif
  155.   
  156.   ifeq ($(CONFIG_UFS_FS),y)
  157. *** linux/fs/devices.c.~1~    Thu May 30 15:49:07 1996
  158. --- linux/fs/devices.c    Thu May 30 15:22:30 1996
  159. ***************
  160. *** 187,201 ****
  161.   }
  162.   
  163.   /*
  164. !  * This routine checks whether a removable media has been changed,
  165. !  * and invalidates all buffer-cache-entries in that case. This
  166. !  * is a relatively slow routine, so we have to try to minimize using
  167. !  * it. Thus it is called only upon a 'mount' or 'open'. This
  168. !  * is the best way of combining speed and utility, I think.
  169. !  * People changing diskettes in the middle of an operation deserve
  170. !  * to loose :-)
  171. !  */
  172. ! int check_disk_change(kdev_t dev)
  173.   {
  174.       int i;
  175.       struct file_operations * fops;
  176. --- 187,200 ----
  177.   }
  178.   
  179.   /*
  180. !  * These routines checks whether a removable media has been changed,
  181. !  * and (for check_disk_change only) invalidate all
  182. !  * buffer-cache-entries in that case. This is a relatively slow
  183. !  * routine, so we have to try to minimize using it. Thus it is called
  184. !  * only upon a 'mount' or 'open'. This is the best way of combining
  185. !  * speed and utility, I think.  People changing diskettes in the
  186. !  * middle of an operation deserve to loose :-) */
  187. ! int query_disk_change(kdev_t dev)
  188.   {
  189.       int i;
  190.       struct file_operations * fops;
  191. ***************
  192. *** 208,224 ****
  193.       if (!fops->check_media_change(dev))
  194.           return 0;
  195.   
  196.       printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
  197.           kdevname(dev));
  198.       for (i=0 ; i<NR_SUPER ; i++)
  199.           if (super_blocks[i].s_dev == dev)
  200.               put_super(super_blocks[i].s_dev);
  201.       invalidate_inodes(dev);
  202.       invalidate_buffers(dev);
  203.   
  204. !     if (fops->revalidate)
  205.           fops->revalidate(dev);
  206. !     return 1;
  207.   }
  208.   
  209.   /*
  210. --- 207,243 ----
  211.       if (!fops->check_media_change(dev))
  212.           return 0;
  213.   
  214. +     return 1;
  215. + }
  216. + int check_disk_change(kdev_t dev)
  217. + {
  218. +     if (!query_disk_change(dev))
  219. +         return 0;
  220.       printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
  221.           kdevname(dev));
  222. +     invalidate_media(dev);
  223. +     return 1;
  224. + }
  225. + void invalidate_media(kdev_t dev) 
  226. + {
  227. +     int i;
  228. +     struct file_operations * fops;
  229. +     
  230. +     i = MAJOR(dev);
  231. +     if (i >= MAX_BLKDEV)
  232. +         return;
  233. +     fops = blkdevs[i].fops;
  234.       for (i=0 ; i<NR_SUPER ; i++)
  235.           if (super_blocks[i].s_dev == dev)
  236.               put_super(super_blocks[i].s_dev);
  237.       invalidate_inodes(dev);
  238.       invalidate_buffers(dev);
  239.   
  240. !     if (fops && fops->revalidate)
  241.           fops->revalidate(dev);
  242. !     return;
  243.   }
  244.   
  245.   /*
  246. *** linux/fs/filesystems.c.~1~    Thu May 30 15:49:07 1996
  247. --- linux/fs/filesystems.c    Thu May 30 15:22:30 1996
  248. ***************
  249. *** 9,14 ****
  250. --- 9,15 ----
  251.   #include <linux/config.h>
  252.   #include <linux/fs.h>
  253.   
  254. + #include <linux/supermount_fs.h>
  255.   #include <linux/minix_fs.h>
  256.   #include <linux/ext_fs.h>
  257.   #include <linux/ext2_fs.h>
  258. ***************
  259. *** 39,44 ****
  260. --- 40,50 ----
  261.       callable = 0;
  262.   
  263.       device_setup();
  264. + #ifdef CONFIG_SUPERMOUNT
  265. +     register_filesystem(&(struct file_system_type)
  266. +         {supermount_read_super, "supermount", 0, NULL});
  267. + #endif
  268.   
  269.       binfmt_setup();
  270.   
  271. *** linux/fs/inode.c.~1~    Thu May 30 15:49:07 1996
  272. --- linux/fs/inode.c    Thu May 30 15:22:30 1996
  273. ***************
  274. *** 219,224 ****
  275. --- 219,226 ----
  276.           if (inode == mount_root && inode->i_count ==
  277.               (inode->i_mount != inode ? 1 : 2))
  278.               continue;
  279. +         if (IS_UNBOUND(inode))
  280. +             continue;
  281.           return 0;
  282.       }
  283.       return 1;
  284. ***************
  285. *** 254,259 ****
  286. --- 256,264 ----
  287.       inode->i_lock = 1;    
  288.       inode->i_sb->s_op->write_inode(inode);
  289.       unlock_inode(inode);
  290. +     if (inode->i_shadow && inode->i_shadow->i_shadow_op && 
  291. +         inode->i_shadow->i_shadow_op->write)
  292. +         inode->i_shadow->i_shadow_op->write(inode->i_shadow);
  293.   }
  294.   
  295.   static inline void read_inode(struct inode * inode)
  296. ***************
  297. *** 414,428 ****
  298.       }
  299.   }
  300.   
  301.   void iput(struct inode * inode)
  302.   {
  303.       if (!inode)
  304.           return;
  305.       wait_on_inode(inode);
  306.       if (!inode->i_count) {
  307.           printk("VFS: iput: trying to free free inode\n");
  308.           printk("VFS: device %s, inode %lu, mode=0%07o\n",
  309. !             kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
  310.           return;
  311.       }
  312.       if (inode->i_pipe)
  313. --- 419,442 ----
  314.       }
  315.   }
  316.   
  317. + static inline void release_shadow(struct inode * inode) {
  318. +     /* Shadow-release should be atomic. */
  319. +     struct inode * tmp;
  320. +     tmp = inode->i_shadow;
  321. +     inode->i_shadow = 0;
  322. + }
  323.   void iput(struct inode * inode)
  324.   {
  325. +     struct inode * shadow;
  326.       if (!inode)
  327.           return;
  328.       wait_on_inode(inode);
  329.       if (!inode->i_count) {
  330.           printk("VFS: iput: trying to free free inode\n");
  331.           printk("VFS: device %s, inode %lu, mode=0%07o\n",
  332. !             kdevname(inode->i_dev), inode->i_ino, inode->i_mode);
  333.           return;
  334.       }
  335.       if (inode->i_pipe)
  336. ***************
  337. *** 441,449 ****
  338.       }
  339.   
  340.       if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
  341.           inode->i_sb->s_op->put_inode(inode);
  342. !         if (!inode->i_nlink)
  343.               return;
  344.       }
  345.   
  346.       if (inode->i_dirt) {
  347. --- 455,476 ----
  348.       }
  349.   
  350.       if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
  351. +         shadow = inode->i_shadow;
  352.           inode->i_sb->s_op->put_inode(inode);
  353. !         if (!inode->i_nlink) {
  354. !             /* The inode should have been cleared, so we
  355. !                            don't reset inode->i_shadow here. */
  356. !             if (shadow) {
  357. !             if (shadow->i_shadow_op && 
  358. !                 shadow->i_shadow_op->release)
  359. !                 shadow->i_shadow_op->release(shadow);
  360. !             iput (shadow);
  361. !             }
  362. !             /* put_inode should do a clear_inode() if the
  363. !                inode is unlinked, so don't bother falling
  364. !                through... */
  365.               return;
  366. +         }
  367.       }
  368.   
  369.       if (inode->i_dirt) {
  370. ***************
  371. *** 473,478 ****
  372. --- 500,513 ----
  373.       }
  374.   
  375.       nr_free_inodes++;
  376. +     shadow = inode->i_shadow;
  377. +     inode->i_shadow = 0;
  378. +     if (shadow) {
  379. +         if (shadow->i_shadow_op && 
  380. +             shadow->i_shadow_op->release)
  381. +             shadow->i_shadow_op->release(shadow);
  382. +         iput (shadow);
  383. +     }
  384.       return;
  385.   }
  386.   
  387. *** linux/fs/open.c.~1~    Thu May 30 15:49:07 1996
  388. --- linux/fs/open.c    Thu May 30 15:22:30 1996
  389. ***************
  390. *** 520,525 ****
  391. --- 520,529 ----
  392.               goto cleanup_inode;
  393.       }
  394.   
  395. +     if (inode->i_shadow && inode->i_shadow->i_shadow_op &&
  396. +         inode->i_shadow->i_shadow_op->open)
  397. +         inode->i_shadow->i_shadow_op->open(inode->i_shadow, flag);
  398.       f->f_inode = inode;
  399.       f->f_pos = 0;
  400.       f->f_reada = 0;
  401. *** linux/fs/super.c.~1~    Thu May 30 15:49:07 1996
  402. --- linux/fs/super.c    Thu May 30 15:40:16 1996
  403. ***************
  404. *** 628,648 ****
  405.    * functions, they should be faked here.  -- jrs
  406.    */
  407.   
  408. ! asmlinkage int sys_umount(char * name)
  409.   {
  410. -     struct inode * inode;
  411.       kdev_t dev;
  412.       int retval;
  413.       struct inode dummy_inode;
  414.   
  415. -     if (!suser())
  416. -         return -EPERM;
  417. -     retval = namei(name, &inode);
  418. -     if (retval) {
  419. -         retval = lnamei(name, &inode);
  420. -         if (retval)
  421. -             return retval;
  422. -     }
  423.       if (S_ISBLK(inode->i_mode)) {
  424.           dev = inode->i_rdev;
  425.           if (IS_NODEV(inode)) {
  426. --- 628,639 ----
  427.    * functions, they should be faked here.  -- jrs
  428.    */
  429.   
  430. ! int do_umounti(struct inode * inode)
  431.   {
  432.       kdev_t dev;
  433.       int retval;
  434.       struct inode dummy_inode;
  435.   
  436.       if (S_ISBLK(inode->i_mode)) {
  437.           dev = inode->i_rdev;
  438.           if (IS_NODEV(inode)) {
  439. ***************
  440. *** 681,730 ****
  441.       return 0;
  442.   }
  443.   
  444.   /*
  445. !  * do_mount() does the actual mounting after sys_mount has done the ugly
  446. !  * parameter parsing. When enough time has gone by, and everything uses the
  447. !  * new mount() parameters, sys_mount() can then be cleaned up.
  448.    *
  449.    * We cannot mount a filesystem if it has active, used, or dirty inodes.
  450.    * We also have to flush all inode-data for this device, as the new mount
  451. !  * might need new info.
  452. !  */
  453.   
  454. ! int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
  455.   {
  456. -     struct inode * dir_i;
  457.       struct super_block * sb;
  458.       struct vfsmount *vfsmnt;
  459. -     int error;
  460.   
  461.       if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
  462.           return -EACCES;
  463.           /*flags |= MS_RDONLY;*/
  464. !     error = namei(dir_name, &dir_i);
  465. !     if (error)
  466. !         return error;
  467. !     if (dir_i->i_count != 1 || dir_i->i_mount) {
  468. !         iput(dir_i);
  469.           return -EBUSY;
  470. !     }
  471. !     if (!S_ISDIR(dir_i->i_mode)) {
  472. !         iput(dir_i);
  473.           return -ENOTDIR;
  474. !     }
  475. !     if (!fs_may_mount(dev)) {
  476. !         iput(dir_i);
  477.           return -EBUSY;
  478. -     }
  479.       sb = read_super(dev,type,flags,data,0);
  480. !     if (!sb) {
  481. !         iput(dir_i);
  482.           return -EINVAL;
  483. !     }
  484. !     if (sb->s_covered) {
  485. !         iput(dir_i);
  486.           return -EBUSY;
  487. -     }
  488.       vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
  489.       if (vfsmnt) {
  490.           vfsmnt->mnt_sb = sb;
  491. --- 672,722 ----
  492.       return 0;
  493.   }
  494.   
  495. + asmlinkage int sys_umount(char * name)
  496. + {
  497. +     struct inode * inode;
  498. +     int retval;
  499. +     if (!suser())
  500. +         return -EPERM;
  501. +     retval = namei(name,&inode);
  502. +     if (retval) {
  503. +         retval = lnamei(name,&inode);
  504. +         if (retval)
  505. +             return retval;
  506. +     }
  507. +     return do_umounti(inode);
  508. + }
  509.   /*
  510. !  * do_mountdev() does the actual mounting after sys_mount has done the
  511. !  * ugly parameter parsing. When enough time has gone by, and
  512. !  * everything uses the new mount() parameters, sys_mount() can then be
  513. !  * cleaned up.
  514.    *
  515.    * We cannot mount a filesystem if it has active, used, or dirty inodes.
  516.    * We also have to flush all inode-data for this device, as the new mount
  517. !  * might need new info.  */
  518.   
  519. ! int do_mountdev(kdev_t dev, struct inode * dir_i, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
  520.   {
  521.       struct super_block * sb;
  522.       struct vfsmount *vfsmnt;
  523.   
  524.       if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
  525.           return -EACCES;
  526.           /*flags |= MS_RDONLY;*/
  527. !     if (dir_i->i_count != 1 || dir_i->i_mount)
  528.           return -EBUSY;
  529. !     if (!S_ISDIR(dir_i->i_mode))
  530.           return -ENOTDIR;
  531. !     if (!fs_may_mount(dev))
  532.           return -EBUSY;
  533.       sb = read_super(dev,type,flags,data,0);
  534. !     if (!sb)
  535.           return -EINVAL;
  536. !     if (sb->s_covered)
  537.           return -EBUSY;
  538.       vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
  539.       if (vfsmnt) {
  540.           vfsmnt->mnt_sb = sb;
  541. ***************
  542. *** 735,740 ****
  543. --- 727,745 ----
  544.       return 0;        /* we don't iput(dir_i) - see umount */
  545.   }
  546.   
  547. + int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
  548. + {
  549. +     int error;
  550. +     struct inode * dir_i;
  551. +     error = namei(dir_name, &dir_i);
  552. +     if (error)
  553. +         return error;
  554. +     error = do_mountdev(dev, dir_i, dev_name, dir_name, type, flags, data);
  555. +     if (error)
  556. +         iput(dir_i);
  557. +     return error;
  558. + }
  559.   
  560.   /*
  561.    * Alters the mount flags of a mounted file system. Only the mount point
  562. ***************
  563. *** 793,810 ****
  564.       *where = 0;
  565.       if (!data)
  566.           return 0;
  567. !     vma = find_vma(current, (unsigned long) data);
  568. !     if (!vma || (unsigned long) data < vma->vm_start)
  569. !         return -EFAULT;
  570. !     if (!(vma->vm_flags & VM_READ))
  571. !         return -EFAULT;
  572. !     i = vma->vm_end - (unsigned long) data;
  573. !     if (PAGE_SIZE <= (unsigned long) i)
  574.           i = PAGE_SIZE-1;
  575.       if (!(page = __get_free_page(GFP_KERNEL))) {
  576.           return -ENOMEM;
  577.       }
  578.       memcpy_fromfs((void *) page,data,i);
  579.       *where = page;
  580.       return 0;
  581. --- 798,818 ----
  582.       *where = 0;
  583.       if (!data)
  584.           return 0;
  585. !     if (get_fs() != get_ds()) {
  586. !         vma = find_vma(current, (unsigned long) data);
  587. !         if (!vma || (unsigned long) data < vma->vm_start)
  588. !             return -EFAULT;
  589. !         if (!(vma->vm_flags & VM_READ))
  590. !             return -EFAULT;
  591. !         i = vma->vm_end - (unsigned long) data;
  592. !         if (PAGE_SIZE <= (unsigned long) i)
  593. !             i = PAGE_SIZE-1;
  594. !     } else
  595.           i = PAGE_SIZE-1;
  596.       if (!(page = __get_free_page(GFP_KERNEL))) {
  597.           return -ENOMEM;
  598.       }
  599.       memcpy_fromfs((void *) page,data,i);
  600.       *where = page;
  601.       return 0;
  602. ***************
  603. *** 825,839 ****
  604.    * version that didn't understand them.
  605.    */
  606.   asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
  607. !     unsigned long new_flags, void * data)
  608.   {
  609. !     struct file_system_type * fstype;
  610. !     struct inode * inode;
  611. !     struct file_operations * fops;
  612. !     kdev_t dev;
  613.       int retval;
  614. -     const char * t;
  615. -     unsigned long flags = 0;
  616.       unsigned long page = 0;
  617.   
  618.       if (!suser())
  619. --- 833,842 ----
  620.    * version that didn't understand them.
  621.    */
  622.   asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
  623. !              unsigned long new_flags, void * data)
  624.   {
  625. !     struct inode * dir_inode;
  626.       int retval;
  627.       unsigned long page = 0;
  628.   
  629.       if (!suser())
  630. ***************
  631. *** 849,854 ****
  632. --- 852,880 ----
  633.           free_page(page);
  634.           return retval;
  635.       }
  636. +     retval = namei(dir_name, &dir_inode);
  637. +     if (retval)
  638. +         return retval;
  639. +     retval = do_mounti(dir_inode,dir_name,dev_name,type,new_flags,data);
  640. +     if (retval)
  641. +         iput(dir_inode);
  642. +     return retval;
  643. + }
  644. + /* Mount on a given inode.  Don't iput() the mount point! */
  645. + int do_mounti(struct inode * dir_inode, const char * dir_name, 
  646. +           const char * dev_name, const char * type, 
  647. +           unsigned long new_flags, const void * data)
  648. + {
  649. +     struct file_system_type * fstype;
  650. +     struct inode * inode;
  651. +     struct file_operations * fops;
  652. +     dev_t dev;
  653. +     int retval;
  654. +     const char * t;
  655. +     unsigned long flags = 0;
  656. +     unsigned long page = 0;
  657.       retval = copy_mount_options (type, &page);
  658.       if (retval < 0)
  659.           return retval;
  660. ***************
  661. *** 906,912 ****
  662.               return retval;
  663.           }
  664.       }
  665. !     retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
  666.       free_page(page);
  667.       if (retval && fops && fops->release)
  668.           fops->release(inode, NULL);
  669. --- 932,939 ----
  670.               return retval;
  671.           }
  672.       }
  673. !     retval = do_mountdev(dev,dir_inode,dev_name,dir_name,
  674. !                  t,flags,(void *) page);
  675.       free_page(page);
  676.       if (retval && fops && fops->release)
  677.           fops->release(inode, NULL);
  678. *** linux/fs/supermount/Makefile.~1~    Thu May 30 15:49:07 1996
  679. --- linux/fs/supermount/Makefile    Thu May 30 15:22:31 1996
  680. ***************
  681. *** 0 ****
  682. --- 1,14 ----
  683. + #
  684. + # Makefile for the linux supermounting routines.
  685. + #
  686. + # Note! Dependencies are done automagically by 'make dep', which also
  687. + # removes any old dependencies. DON'T put your own dependencies here
  688. + # unless it's something special (ie not a .c file).
  689. + #
  690. + # Note 2! The CFLAGS definitions are now in the main makefile...
  691. + O_TARGET := supermount.o
  692. + O_OBJS     := dir.o inode.o namei.o super.o
  693. + M_OBJS     := $(O_TARGET)
  694. + include $(TOPDIR)/Rules.make
  695. *** linux/fs/supermount/TODO.~1~    Thu May 30 15:49:07 1996
  696. --- linux/fs/supermount/TODO    Thu May 30 15:22:31 1996
  697. ***************
  698. *** 0 ****
  699. --- 1,40 ----
  700. + Notes:
  701. + TODO:
  702. +   Supermount directory inodes do auto-remount as root of the subfs.  Make
  703. +   a mount option to restrict this behaviour to the root?
  704. +   Make supermount_attach a special case of read_hidden_inode, not the other
  705. +   way around.
  706. +   Replace shadow inodes with shadow superblock?  Do release that way?
  707. +   Unmount on suspend?  OK iff inode numbers on open directories will
  708. +   be the same next time around!  (Normally true.)  Bad for performance, but
  709. +   maybe necessary for ext2fs, for example.
  710. + Done:::
  711. +   Sigh.  We can't rely on the one-to-one mapping of superinode to
  712. +   subinode i_ino numbers any more.  Why not?  Well, what happens if we
  713. +   remove and remount a medium?  We can end up with one process holding
  714. +   a handle to an old, obsolete superinode, and a new process opening a
  715. +   subinode with the same i_ino.  Well, we can do a quadratic hash on
  716. +   the superinode numbers to avoid collisions.  Think about this!
  717. +   * What happens when we do get an inode collision?  We rehash to make
  718. +     another superinode the current one; the old inode remains as a
  719. +     placeholder.  But then, what if the old inode becomes released?  A
  720. +     subsequent attach may place the subinode under that old inode
  721. +     instead of the new superinode.
  722. +     OK: There is only ever one hidden/shadow connection between super
  723. +     and sub inodes.  If that is broken, we can reestablish it from any
  724. +     superinode we want to.  Previously valid superinodes will have to
  725. +     rely on i_subino to get to their subinode (the subinode i_ino will
  726. +     NOT change behind our backs, hopefully).  Such mappings should
  727. +     only ever be one way, from superinode to subinode, done by
  728. +     subiget().
  729. +   Special handling of root directory to do auto remount.
  730. *** linux/fs/supermount/dir.c.~1~    Thu May 30 15:49:07 1996
  731. --- linux/fs/supermount/dir.c    Thu May 30 15:22:31 1996
  732. ***************
  733. *** 0 ****
  734. --- 1,97 ----
  735. + /*
  736. +  *  linux/fs/supermount/dir.c
  737. +  *
  738. +  *  Copyright (C) 1995
  739. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  740. +  *
  741. +  *  from
  742. +  *
  743. +  *  linux/fs/minix/dir.c
  744. +  *  Copyright (C) 1991, 1992  Linus Torvalds
  745. +  *
  746. +  *  and
  747. +  *
  748. +  *  linux/fs/ext2/dir.c
  749. +  *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  750. +  */
  751. + #include <asm/segment.h>
  752. + #include <linux/errno.h>
  753. + #include <linux/kernel.h>
  754. + #include <linux/fs.h>
  755. + #include <linux/supermount_fs.h>
  756. + #include <linux/stat.h>
  757. + static int supermount_dir_open (struct inode *, struct file *);
  758. + static struct file_operations supermount_dir_operations = {
  759. +     NULL,            /* lseek - default */
  760. +     NULL,            /* read */
  761. +     NULL,            /* write - bad */
  762. +     NULL,            /* readdir */
  763. +     NULL,            /* select - default */
  764. +     NULL,            /* ioctl */
  765. +     NULL,            /* mmap */
  766. +     supermount_dir_open,    /* Redirect to the subfs readdir() code */
  767. +     NULL,            /* no special release code */
  768. +     NULL,            /* fsync */
  769. +     NULL,            /* fasync */
  770. +     NULL,            /* check_media_change */
  771. +     NULL            /* revalidate */
  772. + };
  773. + /*
  774. +  * directories can handle most operations...  supermount/namei.c just
  775. +  * passes them through to the underlying subfs, except for lookup().
  776. +  */
  777. + struct inode_operations supermount_dir_iops = {
  778. +     &supermount_dir_operations,    /* default directory file-ops */
  779. +     supermount_create,        /* create */
  780. +     supermount_lookup,        /* lookup */
  781. +     supermount_link,        /* link */
  782. +     supermount_unlink,        /* unlink */
  783. +     supermount_symlink,        /* symlink */
  784. +     supermount_mkdir,        /* mkdir */
  785. +     supermount_rmdir,        /* rmdir */
  786. +     supermount_mknod,        /* mknod */
  787. +     supermount_rename,        /* rename */
  788. +     NULL,                /* readlink */
  789. +     NULL,                /* follow_link */
  790. +     NULL,                /* bmap */
  791. +     NULL,                /* truncate */
  792. +     supermount_permission,        /* permission */
  793. +     NULL                /* smap */
  794. + };
  795. + /* When we open() a directory (for readdir), just rewrite the file
  796. +    struct to point to the subfs inode, and let it handle all the
  797. +    work. */
  798. + static int supermount_dir_open (struct inode * inode, struct file * file)
  799. + {
  800. +     struct inode * subi;
  801. +     int rc;
  802. +     
  803. +     if (file->f_mode & 2)
  804. +         return -EPERM;
  805. +     supermount_debug ("dir_open inode %ld\n", inode->i_ino);
  806. +     
  807. +     subi = subiget(inode);
  808. +     if (!subi)
  809. +         return -ENOENT;
  810. +     file->f_inode = subi;
  811. +     file->f_op = subi->i_op ? subi->i_op->default_file_ops : NULL;
  812. +     if (file->f_op && file->f_op->open) {
  813. +         rc = file->f_op->open(subi, file);
  814. +         if (rc) {
  815. +             iput(subi);
  816. +             return rc;
  817. +         }
  818. +     }
  819. +     iput(inode);
  820. +     return 0;
  821. + }
  822. *** linux/fs/supermount/file.c.~1~    Thu May 30 15:49:07 1996
  823. --- linux/fs/supermount/file.c    Thu May 30 15:22:31 1996
  824. ***************
  825. *** 0 ****
  826. --- 1,21 ----
  827. + /*
  828. +  *  linux/fs/supermount/file.c
  829. +  *
  830. +  *  Copyright (C) 1995
  831. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  832. +  *
  833. +  */
  834. + #include <asm/segment.h>
  835. + #include <asm/system.h>
  836. + #include <linux/errno.h>
  837. + #include <linux/fs.h>
  838. + #include <linux/supermount_fs.h>
  839. + #include <linux/fcntl.h>
  840. + #include <linux/sched.h>
  841. + #include <linux/stat.h>
  842. + #include <linux/locks.h>
  843. + static void supermount_inode_release (struct inode *);
  844. *** linux/fs/supermount/inode.c.~1~    Thu May 30 15:49:07 1996
  845. --- linux/fs/supermount/inode.c    Thu May 30 15:22:31 1996
  846. ***************
  847. *** 0 ****
  848. --- 1,380 ----
  849. + /*
  850. +  *  linux/fs/supermount/inode.c
  851. +  *
  852. +  *  Copyright (C) 1995
  853. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  854. +  *
  855. +  *  from
  856. +  *
  857. +  *  linux/fs/minix/inode.c
  858. +  *  Copyright (C) 1991, 1992  Linus Torvalds
  859. +  *
  860. +  *  and
  861. +  *
  862. +  *  linux/fs/ext2/inode.c
  863. +  *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  864. +  *  and           1993  Stephen Tweedie
  865. +  */
  866. + #include <asm/segment.h>
  867. + #include <asm/system.h>
  868. + #include <linux/errno.h>
  869. + #include <linux/fs.h>
  870. + #include <linux/supermount_fs.h>
  871. + #include <linux/sched.h>
  872. + #include <linux/stat.h>
  873. + #include <linux/string.h>
  874. + #include <linux/locks.h>
  875. + #include <linux/mm.h>
  876. + static void read_hidden_inode (struct inode *);
  877. + static void supermount_inode_open (struct inode *, int);
  878. + static void supermount_inode_write (struct inode *);
  879. + static void supermount_inode_release (struct inode *);
  880. + /* Deal with the shadow interface.  Whenever a subfs inode is
  881. +    released, break the bi-directional link between them, and close and
  882. +    iput the supermount inode.  */
  883. + struct inode_shadow_operations supermount_shadow_iops = {
  884. +     supermount_inode_open,
  885. +     supermount_inode_write,
  886. +     supermount_inode_release,
  887. + };
  888. + void supermount_inode_open (struct inode *inode, int flag)
  889. + {
  890. +     if (flag & 2)
  891. +         mark_subfs_dirty(inode->i_sb);
  892. + }
  893. + void supermount_inode_write (struct inode *inode)
  894. + {
  895. +     mark_subfs_dirty(inode->i_sb);
  896. + }
  897. + void supermount_inode_release (struct inode *inode)
  898. + {
  899. +     supermount_debug ("inode = %ld\n", inode->i_ino);
  900. +     if (inode->u.supermount_i.i_hidden)
  901. +         supermount_debug("subinode = %ld\n", 
  902. +                  inode->u.supermount_i.i_hidden->i_ino);
  903. +     
  904. +     inode->u.supermount_i.i_hidden = NULL;
  905. +     supermount_iclose(inode);
  906. + }
  907. + /* Do an iget on the appropriate subfs inode */
  908. + struct inode * subiget(struct inode * inode) 
  909. + {
  910. +     struct inode * tmp;
  911. +     supermount_debug("subiget inode %ld\n", inode->i_ino);
  912. +     if (!S_ISDIR(inode->i_mode))
  913. +         return 0;
  914. +     if (supermount_media_check(inode->i_sb)) {
  915. +         supermount_debug("media is invalid\n");
  916. +         return 0;
  917. +     }
  918. +     
  919. +     if (inode_is_obsolete(inode)) {
  920. +         /* For obsolete directory with new mounted media ---
  921. +                    return the new root subinode. */
  922. +         if (inode->u.supermount_i.i_hidden) 
  923. +             supermount_panic (inode->i_sb, "subiget", 
  924. +                       "Hidden inode on obsolete inode %ld",
  925. +                       inode->i_ino);
  926. +         tmp = inode->i_sb->u.supermount_sb.s_subfs->s_mounted;
  927. +         inode->u.supermount_i.i_subino = tmp->i_ino;
  928. +         tmp->i_count++;
  929. +         supermount_debug("mapping obsolete inode %ld to "
  930. +                  "subroot inode %ld\n",
  931. +                  inode->i_ino, tmp->i_ino);
  932. +         return tmp;
  933. +     }
  934. +     
  935. +     if (inode->u.supermount_i.i_hidden) {
  936. +         inode->u.supermount_i.i_hidden->i_count++;
  937. +         supermount_debug("inode %ld/%ld, found hidden, "
  938. +                  "count now %d/%d\n",
  939. +                  inode->i_ino,
  940. +                  inode->u.supermount_i.i_hidden->i_ino,
  941. +                  inode->i_count,
  942. +                  inode->u.supermount_i.i_hidden->i_count);
  943. +         return inode->u.supermount_i.i_hidden;
  944. +     }
  945. +     read_hidden_inode(inode);
  946. +     if (!inode->u.supermount_i.i_hidden) {
  947. +         supermount_debug("inode %ld, no subinode, count=%d\n",
  948. +                  inode->i_ino, inode->i_count);
  949. +         return 0;
  950. +     }
  951. +     
  952. +     supermount_debug("inode %ld/%ld, found new, "
  953. +              "count now %d/%d\n",
  954. +              inode->i_ino,
  955. +              inode->u.supermount_i.i_hidden->i_ino,
  956. +              inode->i_count,
  957. +              inode->u.supermount_i.i_hidden->i_count);
  958. +     return inode->u.supermount_i.i_hidden;
  959. + }
  960. + /* We sometimes do a lookup on a subinode and want to get back a
  961. +    superinode in return, with a single iget() outstanding on both (not
  962. +    counting the i_shadow reference).  supermount_attach generates the
  963. +    superinode for a given subinode. */
  964. + struct inode * supermount_attach(struct super_block *sb, struct inode *inode) 
  965. + {
  966. +     struct inode *tmp;
  967. +     unsigned long new_ino, incr=1237;
  968. +     
  969. +     supermount_debug ("inode = %ld\n", inode->i_ino);
  970. +     
  971. +     if (inode->i_shadow) {
  972. +         supermount_debug ("return existing shadow %ld, count %d/%d\n",
  973. +                   inode->i_shadow->i_ino,
  974. +                   inode->i_shadow->i_count, inode->i_count);
  975. +         inode->i_shadow->i_count++;
  976. +         return inode->i_shadow;
  977. +     }
  978. +     
  979. +     /* The rules are a little different at the root. */
  980. +     if (inode == sb->u.supermount_sb.s_subfs->s_mounted) {
  981. +         tmp = sb->s_mounted;
  982. +         supermount_debug ("return existing superfs root %ld, "
  983. +                   "count %d/%d\n",
  984. +                   tmp->i_ino, tmp->i_count, inode->i_count);
  985. +         tmp->i_count++;
  986. +         return tmp;
  987. +     }
  988. +     /* Find a new superinode, avoiding collisions with old
  989. +            obsolete superinodes by a quadratic hash. */
  990. +     new_ino = inode->i_ino;
  991. +     for ( ; (tmp = iget(sb, new_ino)) && tmp->i_count > 1 &&
  992. +             inode_is_obsolete(tmp); ) {
  993. +         iput(tmp);
  994. +         new_ino += incr;
  995. +         new_ino &= 0xffffff;
  996. +         incr <<= 1; incr++;
  997. +     }
  998. +     
  999. +     tmp->u.supermount_i.i_subino = inode->i_ino;
  1000. +     /* If we found a previously obsolete inode which is now no
  1001. +            longer used, we can safely remove the obsolesence flag. */
  1002. +     if (inode_is_obsolete(tmp)) {
  1003. +         tmp->u.supermount_i.i_sb_version = 
  1004. +             tmp->i_sb->u.supermount_sb.s_version;
  1005. +     }
  1006. +     
  1007. +     /* We have now done iget() on superi and subi.  Doing the
  1008. +            attachment may incur another iget() on the subinode. */
  1009. +     if (!tmp->u.supermount_i.i_hidden) {
  1010. +         read_hidden_inode(tmp);
  1011. +         iput(inode);
  1012. +     }
  1013. +     return tmp;
  1014. + }
  1015. + /* Supermount open/close inode.  These functions maintain the
  1016. +    superblock reference counts of active inodes; the subfs is
  1017. +    suspended when that count reaches zero.
  1018. +    Files are opened on any significant reference, and are not closed
  1019. +    until they become fully dereferenced (during the last iput).
  1020. +    Directories, on the other hand, are always closed unless they are
  1021. +    active and opened; a directory referenced as CWD is not open.
  1022. +    The difference is in the way the application gets given inodes.
  1023. +    For dirs and symlinks, it will be given the superinode to deal
  1024. +    with; for other file types, we return the subinode. */
  1025. + void supermount_iopen(struct inode * inode)
  1026. + {
  1027. +     supermount_debug ("inode %ld, count %d\n", 
  1028. +               inode->i_ino, inode->i_count);
  1029. +     if (inode->i_sb->u.supermount_sb.s_state == SUPERMOUNT_UNMOUNTED)
  1030. +         supermount_panic (inode->i_sb, "supermount_iopen", 
  1031. +                   "opening inode on unmounted subfs");
  1032. +     if (!inode->u.supermount_i.i_counted) {
  1033. +         supermount_debug("Opened inode %ld\n", inode->i_ino);
  1034. +         inode->u.supermount_i.i_counted = 1;
  1035. +         if (!subfs_is_active(inode->i_sb)) {
  1036. +             supermount_debug ("going online.\n");
  1037. +             inode->i_sb->u.supermount_sb.s_state = 
  1038. +                 SUPERMOUNT_ONLINE;
  1039. +         }
  1040. +         inode->i_sb->u.supermount_sb.s_opencount++;
  1041. +     }
  1042. + }
  1043. + void supermount_iclose(struct inode * inode)
  1044. + {
  1045. +     supermount_debug ("inode %ld, count %d\n", 
  1046. +               inode->i_ino, inode->i_count);
  1047. +     if (inode->u.supermount_i.i_counted) {
  1048. +         supermount_debug("Closed inode %ld\n", inode->i_ino);
  1049. +         inode->u.supermount_i.i_counted = 0;
  1050. +         inode->i_sb->u.supermount_sb.s_opencount--;
  1051. +         if (!subfs_is_active(inode->i_sb))
  1052. +             supermount_go_inactive(inode->i_sb);
  1053. +     }
  1054. + }
  1055. + void supermount_go_inactive(struct super_block *sb)
  1056. + {
  1057. +     supermount_debug("Checking state\n");
  1058. +     if (!subfs_is_active(sb)) {
  1059. +         supermount_debug("going offline.\n");
  1060. +         sb->u.supermount_sb.s_state = 
  1061. +             SUPERMOUNT_SUSPENDED;
  1062. +         if (subfs_is_dirty(sb)) {
  1063. +             mark_subfs_clean(sb);
  1064. +             fsync_dev(sb->u.supermount_sb.s_subfs->s_dev);
  1065. +         }
  1066. +     }
  1067. + }
  1068. + static void read_hidden_inode (struct inode * inode)
  1069. + {
  1070. +     struct super_block * sb;
  1071. +     struct inode * tmp;
  1072. +     supermount_debug("inode = %ld\n", inode->i_ino);
  1073. +     supermount_media_check(inode->i_sb);
  1074. +     if (inode->i_sb->u.supermount_sb.s_state ==
  1075. +         SUPERMOUNT_UNMOUNTED) {
  1076. +         supermount_panic (inode->i_sb, "read_hidden_inode",
  1077. +                   "Trying to read inode on unmounted media");
  1078. +     }
  1079. +     sb=inode->i_sb->u.supermount_sb.s_subfs;
  1080. +     /* The root inode is a bit special.  For that one, the
  1081. +            subinode is the root of the subfs, and we can't guarantee
  1082. +            its inode number in advance. */
  1083. +     if (inode->i_ino == SUPERMOUNT_ROOT_INO) {
  1084. +         tmp = sb->s_mounted;
  1085. +         tmp->i_count++;
  1086. +     } else {
  1087. +         if (!inode->u.supermount_i.i_subino)
  1088. +             inode->u.supermount_i.i_subino = inode->i_ino;
  1089. +         tmp = iget(sb, inode->u.supermount_i.i_subino);
  1090. +     }
  1091. +     if (!tmp)
  1092. +         return;
  1093. +     /* If the inode is already linked to its superinode, don't do
  1094. +            any further processing.  Also, don't bother trying to
  1095. +            attach to the superinode if we are reading from an obsolete
  1096. +            superinode. */
  1097. +     if (tmp->i_shadow || inode_is_obsolete(inode))
  1098. +         return;
  1099. +     tmp->i_shadow = inode;
  1100. +     inode->u.supermount_i.i_hidden = tmp;
  1101. +     inode->i_count++;
  1102. +     supermount_iopen(inode);
  1103. +     inode->i_mode = tmp->i_mode;
  1104. +     inode->i_uid = tmp->i_uid;
  1105. +     inode->i_gid = tmp->i_gid;
  1106. +     inode->i_nlink = tmp->i_nlink;
  1107. +     inode->i_size = tmp->i_size;
  1108. +     inode->i_atime = tmp->i_atime;
  1109. +     inode->i_ctime = tmp->i_ctime;
  1110. +     inode->i_mtime = tmp->i_mtime;
  1111. +     inode->i_blksize = tmp->i_blksize;
  1112. +     inode->i_blocks = tmp->i_blocks;
  1113. +     inode->i_rdev = tmp->i_rdev;
  1114. +     inode->i_version = ++event;
  1115. +     if (S_ISDIR(inode->i_mode))
  1116. +         inode->i_op = &supermount_dir_iops;
  1117. +     else
  1118. +         inode->i_op = NULL;
  1119. + }
  1120. + void supermount_read_inode (struct inode * inode)
  1121. + {
  1122. +     supermount_debug ("inode = %ld\n", inode->i_ino);
  1123. +     
  1124. +     inode->i_shadow_op = &supermount_shadow_iops;
  1125. +     inode->u.supermount_i.i_sb_version = 
  1126. +         inode->i_sb->u.supermount_sb.s_version;
  1127. +     
  1128. +     switch (inode->i_ino) {
  1129. +     case SUPERMOUNT_ROOT_INO:
  1130. +         if (inode->i_sb->u.supermount_sb.s_state !=
  1131. +             SUPERMOUNT_UNMOUNTED) {
  1132. +             supermount_panic (inode->i_sb, "supermount_read_inode",
  1133. +                       "Help - trying to read root while "
  1134. +                       "already mounted!");
  1135. +         }
  1136. +         /* Fall through */
  1137. +     case SUPERMOUNT_HIDDEN_INO:
  1138. +         inode->i_mode = inode->i_sb->u.supermount_sb.s_default_mode;
  1139. +         inode->i_uid = 0;
  1140. +         inode->i_gid = 0;
  1141. +         inode->i_nlink = 1;
  1142. +         inode->i_size = 0;
  1143. +         inode->i_atime = CURRENT_TIME;
  1144. +         inode->i_ctime = CURRENT_TIME;
  1145. +         inode->i_mtime = CURRENT_TIME;
  1146. +         inode->i_blksize = inode->i_sb->s_blocksize;
  1147. +         inode->i_blocks = 0;
  1148. +         inode->i_version = ++event;
  1149. +         inode->i_op = (inode->i_ino == SUPERMOUNT_ROOT_INO)
  1150. +             ? &supermount_dir_iops : NULL;
  1151. +         return;
  1152. +     default:
  1153. +         ;
  1154. +     }
  1155. + }
  1156. + void supermount_write_inode (struct inode * inode)
  1157. + {
  1158. +     struct super_block *tmp;
  1159. +     tmp = inode->i_sb->u.supermount_sb.s_subfs;
  1160. +     
  1161. +     if (inode->u.supermount_i.i_hidden &&
  1162. +         tmp && tmp->s_op && tmp->s_op->write_inode)
  1163. +         tmp->s_op->write_inode(inode->u.supermount_i.i_hidden);
  1164. +     mark_subfs_dirty(inode->i_sb);
  1165. + }
  1166. + int supermount_permission (struct inode * inode, int mask)
  1167. + {
  1168. +     unsigned short mode;
  1169. +     struct inode *subi;
  1170. +     supermount_debug("inode %ld, mask 0%o\n", inode->i_ino, mask);
  1171. +     subi = subiget(inode);
  1172. +     if (!subi)
  1173. +         return -EIO;
  1174. +     if (subi->i_op && subi->i_op->permission) {
  1175. +         int rc = subi->i_op->permission(subi, mask);
  1176. +         iput(subi);
  1177. +         return rc;
  1178. +     }
  1179. +     
  1180. +     mode = inode->i_mode;
  1181. +     /*
  1182. +      * Special case, access is always granted for root
  1183. +      */
  1184. +     if (fsuser()) {
  1185. +         iput(subi);
  1186. +         return 0;
  1187. +     } else if (current->fsuid == inode->i_uid)
  1188. +         mode >>= 6;
  1189. +     else if (in_group_p (inode->i_gid))
  1190. +         mode >>= 3;
  1191. +     iput(subi);
  1192. +     if (((mode & mask & S_IRWXO) == mask))
  1193. +         return 0;
  1194. +     else
  1195. +         return -EACCES;
  1196. + }
  1197. *** linux/fs/supermount/namei.c.~1~    Thu May 30 15:49:07 1996
  1198. --- linux/fs/supermount/namei.c    Thu May 30 15:22:31 1996
  1199. ***************
  1200. *** 0 ****
  1201. --- 1,347 ----
  1202. + /*
  1203. +  *  linux/fs/supermount/namei.c
  1204. +  *
  1205. +  *  Copyright (C) 1995
  1206. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  1207. +  *
  1208. +  *  from
  1209. +  *
  1210. +  *  linux/fs/minix/namei.c
  1211. +  *  Copyright (C) 1991, 1992  Linus Torvalds
  1212. +  *
  1213. +  *  and
  1214. +  *
  1215. +  *  linux/fs/ext2/namei.c
  1216. +  *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  1217. +  */
  1218. + /* This file handles almost all of the normal filesystem running of
  1219. +    supermount.  We don't have to deal to much with the subfs
  1220. +    interface, since we just pass subinodes out to the application on
  1221. +    demand. */
  1222. + #include <asm/segment.h>
  1223. + #include <linux/errno.h>
  1224. + #include <linux/fs.h>
  1225. + #include <linux/supermount_fs.h>
  1226. + #include <linux/fcntl.h>
  1227. + #include <linux/sched.h>
  1228. + #include <linux/stat.h>
  1229. + #include <linux/string.h>
  1230. + #include <linux/locks.h>
  1231. + /* Attach a superinode to a subinode, and prepare a result for the
  1232. +    upper VFS layers.  We return the superinode for directories, and
  1233. +    the subinode for other file types.
  1234. +    */
  1235. + static void attach_and_prepare(struct super_block *sb,
  1236. +                    struct inode *subi, struct inode **result)
  1237. + {
  1238. +     struct inode *superi;
  1239. +     superi = supermount_attach(sb, subi);
  1240. +     /* We have now done iget() on superi and subi. */
  1241. +     
  1242. +     /* If the subfs inode is a directory or a symlink, then we
  1243. +        need to deal with it ourselves, and only give back the
  1244. +        superinode to the application.  Otherwise, we can just
  1245. +        return the subfs inode. */
  1246. +     if (S_ISDIR(subi->i_mode)) {
  1247. +         superi->i_op = &supermount_dir_iops;
  1248. +         iput(subi);
  1249. +         *result = superi;
  1250. +         return;
  1251. +     } else {
  1252. +         /* Not a directory-related inode, so we return the
  1253. +            subfs inode to the upper layers.  We still need the
  1254. +            supermount inode in that case, though, to maintain
  1255. +            reference counts in the supermount superblock. */
  1256. +         iput(superi);
  1257. +         *result = subi;
  1258. +         return;
  1259. +     }
  1260. + }
  1261. + int supermount_lookup (struct inode * dir, const char * name, int len,
  1262. +                struct inode ** result)
  1263. + {
  1264. +     struct inode *subi, *subdir;
  1265. +     int rc;
  1266. +     
  1267. +     supermount_debug ("inode = %ld, name = %*s\n",
  1268. +               dir->i_ino, len, name);
  1269. +     *result = NULL;
  1270. +     if (!dir)
  1271. +         return -ENOENT;
  1272. +     if (!S_ISDIR(dir->i_mode)) {
  1273. +         iput(dir);
  1274. +         return -ENOENT;
  1275. +     }
  1276. +     if (!(subdir = subiget(dir)))  {
  1277. +         /* This now becomes the *easy* case. :-) */
  1278. +         iput (dir);
  1279. +         return -EIO;
  1280. +     }
  1281. +     rc = subdir->i_op->lookup(subdir, name, len, &subi);
  1282. +     supermount_go_inactive(dir->i_sb);
  1283. +     iput (dir);
  1284. +     if (rc)
  1285. +         return rc;
  1286. +     /* It worked, so now create a shadow supermount inode for the
  1287. +            result... */
  1288. +     attach_and_prepare(dir->i_sb, subi, result);
  1289. +     return 0;
  1290. + }
  1291. + int supermount_create (struct inode * dir,const char * name, int len, int mode,
  1292. +                struct inode ** result)
  1293. + {
  1294. +     struct inode * inode, * subi;
  1295. +     int rc;
  1296. +     
  1297. +     supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1298. +               dir->i_ino, len, name, mode);
  1299. +     *result = NULL;
  1300. +     if (!dir)
  1301. +         return -ENOENT;
  1302. +     inode = subiget(dir);
  1303. +     if (!inode) {
  1304. +         iput(dir);
  1305. +         return -ENOENT;
  1306. +     }
  1307. +     if (!inode->i_op || !inode->i_op->create) {
  1308. +         iput(dir);
  1309. +         iput(inode);
  1310. +         return -EPERM;
  1311. +     }
  1312. +     
  1313. +     rc = inode->i_op->create(inode, name, len, mode, &subi);
  1314. +     mark_subfs_dirty(dir->i_sb);
  1315. +     supermount_go_inactive(dir->i_sb);
  1316. +     iput(dir);
  1317. +     if (rc)
  1318. +         return rc;
  1319. +     attach_and_prepare(dir->i_sb, subi, result);
  1320. +     return 0;
  1321. + }
  1322. + int supermount_mknod (struct inode * dir, const char * name, int len, int mode,
  1323. +               int rdev)
  1324. + {
  1325. +     struct inode * inode;
  1326. +     int rc;
  1327. +     
  1328. +     supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1329. +               dir->i_ino, len, name, mode);
  1330. +     if (!dir)
  1331. +         return -ENOENT;
  1332. +     inode = subiget(dir);
  1333. +     if (!inode) {
  1334. +         iput(dir);
  1335. +         return -ENOENT;
  1336. +     }
  1337. +     if (!inode->i_op || !inode->i_op->mknod) {
  1338. +         iput(dir);
  1339. +         iput(inode);
  1340. +         return -EPERM;
  1341. +     }
  1342. +     
  1343. +     rc = inode->i_op->mknod(inode, name, len, mode, rdev);
  1344. +     mark_subfs_dirty(dir->i_sb);
  1345. +     supermount_go_inactive(dir->i_sb);
  1346. +     iput(dir);
  1347. +     return rc;
  1348. + }
  1349. + int supermount_mkdir (struct inode * dir, const char * name, int len, int mode)
  1350. + {
  1351. +     struct inode * inode;
  1352. +     int rc;
  1353. +     
  1354. +     supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1355. +               dir->i_ino, len, name, mode);
  1356. +     if (!dir)
  1357. +         return -ENOENT;
  1358. +     inode = subiget(dir);
  1359. +     if (!inode) {
  1360. +         iput(dir);
  1361. +         return -ENOENT;
  1362. +     }
  1363. +     if (!inode->i_op || !inode->i_op->mkdir) {
  1364. +         iput(dir);
  1365. +         iput(inode);
  1366. +         return -EPERM;
  1367. +     }
  1368. +     
  1369. +     rc = inode->i_op->mkdir(inode, name, len, mode);
  1370. +     mark_subfs_dirty(dir->i_sb);
  1371. +     supermount_go_inactive(dir->i_sb);
  1372. +     iput(dir);
  1373. +     return rc;
  1374. + }
  1375. + int supermount_rmdir (struct inode * dir, const char * name, int len)
  1376. + {
  1377. +     struct inode * inode;
  1378. +     int rc;
  1379. +     
  1380. +     supermount_debug ("inode = %ld, name = %*s\n",
  1381. +               dir->i_ino, len, name);
  1382. +     if (!dir)
  1383. +         return -ENOENT;
  1384. +     inode = subiget(dir);
  1385. +     if (!inode) {
  1386. +         iput(dir);
  1387. +         return -ENOENT;
  1388. +     }
  1389. +     if (!inode->i_op || !inode->i_op->rmdir) {
  1390. +         iput(dir);
  1391. +         iput(inode);
  1392. +         return -EPERM;
  1393. +     }
  1394. +     
  1395. +     rc = inode->i_op->rmdir(inode, name, len);
  1396. +     mark_subfs_dirty(dir->i_sb);
  1397. +     supermount_go_inactive(dir->i_sb);
  1398. +     iput(dir);
  1399. +     return rc;
  1400. + }
  1401. + int supermount_unlink (struct inode * dir, const char * name, int len)
  1402. + {
  1403. +     struct inode * inode;
  1404. +     int rc;
  1405. +     
  1406. +     supermount_debug ("inode = %ld, name = %*s\n",
  1407. +               dir->i_ino, len, name);
  1408. +     if (!dir)
  1409. +         return -ENOENT;
  1410. +     inode = subiget(dir);
  1411. +     if (!inode) {
  1412. +         iput(dir);
  1413. +         return -ENOENT;
  1414. +     }
  1415. +     if (!inode->i_op || !inode->i_op->unlink) {
  1416. +         iput(dir);
  1417. +         iput(inode);
  1418. +         return -EPERM;
  1419. +     }
  1420. +     
  1421. +     rc = inode->i_op->unlink(inode, name, len);
  1422. +     mark_subfs_dirty(dir->i_sb);
  1423. +     supermount_go_inactive(dir->i_sb);
  1424. +     iput(dir);
  1425. +     return rc;
  1426. + }
  1427. + int supermount_symlink (struct inode * dir, const char * name, int len,
  1428. +             const char * symname)
  1429. + {
  1430. +     struct inode * inode;
  1431. +     int rc;
  1432. +     
  1433. +     supermount_debug ("inode = %ld, name = %*s, link = %s\n",
  1434. +               dir->i_ino, len, name, symname);
  1435. +     if (!dir)
  1436. +         return -ENOENT;
  1437. +     inode = subiget(dir);
  1438. +     if (!inode) {
  1439. +         iput(dir);
  1440. +         return -ENOENT;
  1441. +     }
  1442. +     if (!inode->i_op || !inode->i_op->symlink) {
  1443. +         iput(dir);
  1444. +         iput(inode);
  1445. +         return -EPERM;
  1446. +     }
  1447. +     
  1448. +     rc = inode->i_op->symlink(inode, name, len, symname);
  1449. +     mark_subfs_dirty(dir->i_sb);
  1450. +     supermount_go_inactive(dir->i_sb);
  1451. +     iput(dir);
  1452. +     return rc;
  1453. + }
  1454. + /* This probably won't work because higher levels will complain about
  1455. +    cross-device links. */
  1456. + int supermount_link (struct inode * oldinode, struct inode * dir,
  1457. +              const char * name, int len)
  1458. + {
  1459. +     struct inode * inode;
  1460. +     int rc;
  1461. +     
  1462. +     supermount_debug ("inode = %ld, name = %*s, link to inode %ld\n",
  1463. +               dir->i_ino, len, name, oldinode->i_ino);
  1464. +     if (!dir)
  1465. +         return -ENOENT;
  1466. +     inode = subiget(dir);
  1467. +     if (!inode) {
  1468. +         iput(dir);
  1469. +         return -ENOENT;
  1470. +     }
  1471. +     if (!inode->i_op || !inode->i_op->link) {
  1472. +         iput(dir);
  1473. +         iput(inode);
  1474. +         return -EPERM;
  1475. +     }
  1476. +     
  1477. +     rc = inode->i_op->link(oldinode, inode, name, len);
  1478. +     mark_subfs_dirty(dir->i_sb);
  1479. +     supermount_go_inactive(dir->i_sb);
  1480. +     iput(dir);
  1481. +     return rc;
  1482. + }
  1483. + int supermount_rename (struct inode * old_dir, const char * old_name, 
  1484. +                int old_len,
  1485. +                struct inode * new_dir, const char * new_name, 
  1486. +                int new_len)
  1487. + {
  1488. +     struct inode * old_subi, * new_subi;
  1489. +     int rc;
  1490. +     
  1491. +     supermount_debug ("from inode %ld, %*s to inode %ld, %*s\n",
  1492. +               old_dir->i_ino, old_len, old_name,
  1493. +               new_dir->i_ino, new_len, new_name);
  1494. +     if (!old_dir || !new_dir)
  1495. +         return -ENOENT;
  1496. +     old_subi = subiget(old_dir);
  1497. +     if (!old_subi) {
  1498. +         iput(old_dir);
  1499. +         iput(new_dir);
  1500. +         return -ENOENT;
  1501. +     }
  1502. +     new_subi = subiget(new_dir);
  1503. +     if (!new_subi) {
  1504. +         iput(old_dir);
  1505. +         iput(new_dir);
  1506. +         iput(old_subi);
  1507. +         return -ENOENT;
  1508. +     }
  1509. +     if (!old_subi->i_op || !old_subi->i_op->rename) {
  1510. +         iput(old_dir);
  1511. +         iput(new_dir);
  1512. +         iput(old_subi);
  1513. +         iput(new_subi);
  1514. +         return -EPERM;
  1515. +     }
  1516. +     
  1517. +     rc = old_subi->i_op->rename(old_subi, old_name, old_len,
  1518. +                     new_subi, new_name, new_len);
  1519. +     mark_subfs_dirty(old_dir->i_sb);
  1520. +     supermount_go_inactive(old_dir->i_sb);
  1521. +     iput(old_dir);
  1522. +     iput(new_dir);
  1523. +     return rc;
  1524. + }
  1525. *** linux/fs/supermount/super.c.~1~    Thu May 30 15:49:07 1996
  1526. --- linux/fs/supermount/super.c    Thu May 30 15:22:31 1996
  1527. ***************
  1528. *** 0 ****
  1529. --- 1,430 ----
  1530. + /*
  1531. +  *  linux/fs/supermount/super.c
  1532. +  *
  1533. +  *  Copyright (C) 1995
  1534. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  1535. +  *
  1536. +  *  from
  1537. +  *
  1538. +  *  linux/fs/minix/inode.c
  1539. +  *  Copyright (C) 1991, 1992  Linus Torvalds
  1540. +  *
  1541. +  *  and
  1542. +  *
  1543. +  *  linux/fs/ext2/super.c
  1544. +  *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  1545. +  */
  1546. + #include <stdarg.h>
  1547. + #include <asm/segment.h>
  1548. + #include <asm/system.h>
  1549. + #include <linux/errno.h>
  1550. + #include <linux/fs.h>
  1551. + #include <linux/supermount_fs.h>
  1552. + #include <linux/malloc.h>
  1553. + #include <linux/sched.h>
  1554. + #include <linux/stat.h>
  1555. + #include <linux/string.h>
  1556. + #include <linux/locks.h>
  1557. + #include <linux/major.h>
  1558. + /* From fs/super.c */
  1559. + extern int do_umount(kdev_t);
  1560. + #ifdef SUPERMOUNT_DEBUG
  1561. + char supermount_debug_enable = 0;
  1562. + #endif
  1563. + static struct super_operations supermount_sops = { 
  1564. +     supermount_read_inode,
  1565. +     NULL,
  1566. +     supermount_write_inode,
  1567. +     NULL,                /* put_inode */
  1568. +     supermount_put_super,
  1569. +     supermount_write_super,
  1570. +     supermount_statfs,
  1571. +     NULL,                 /* supermount_remount */
  1572. + };
  1573. + static char error_buf[1024];
  1574. + /* Mount and mount the hidden fs */
  1575. + static void umount_subfs(struct super_block *);
  1576. + void supermount_error (struct super_block * sb, const char * function,
  1577. +                const char * fmt, ...)
  1578. + {
  1579. +     va_list args;
  1580. +     va_start (args, fmt);
  1581. +     vsprintf (error_buf, fmt, args);
  1582. +     va_end (args);
  1583. +     printk (KERN_CRIT "SUPERMOUNT error (device %d/%d): %s: %s\n",
  1584. +         MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1585. +     /* @@ Do we want to do any special error handling here? */
  1586. + }
  1587. + NORET_TYPE void supermount_panic (struct super_block * sb, const char * function,
  1588. +                 const char * fmt, ...)
  1589. + {
  1590. +     va_list args;
  1591. +     va_start (args, fmt);
  1592. +     vsprintf (error_buf, fmt, args);
  1593. +     va_end (args);
  1594. +     panic ("SUPERMOUNT panic (device %d/%d): %s: %s\n",
  1595. +            MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1596. + }
  1597. + void supermount_warning (struct super_block * sb, const char * function,
  1598. +            const char * fmt, ...)
  1599. + {
  1600. +     va_list args;
  1601. +     va_start (args, fmt);
  1602. +     vsprintf (error_buf, fmt, args);
  1603. +     va_end (args);
  1604. +     printk (KERN_WARNING "SUPERMOUNT-fs warning (device %d/%d): %s: %s\n",
  1605. +         MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1606. + }
  1607. + /* Release the superblock and any resources it has reserved */
  1608. + void supermount_put_super (struct super_block * sb)
  1609. + {
  1610. +     lock_super (sb);
  1611. +     if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED)
  1612. +         umount_subfs (sb);
  1613. +     sb->s_dev = 0;
  1614. +     unlock_super (sb);
  1615. + }
  1616. + static int copy_option(const char **option, const char *val)
  1617. + {
  1618. +     char *tmp;
  1619. +     supermount_debug ("assigning value \"%s\"\n", val);
  1620. +     if (!val || !*val)
  1621. +         return -EINVAL;
  1622. +     tmp = (char *) kmalloc(1 + strlen(val), GFP_KERNEL);
  1623. +     if (!tmp)
  1624. +         return -ENOMEM;
  1625. +     strcpy(tmp, val);
  1626. +     *option = tmp;
  1627. +     return 0;
  1628. + }
  1629. + /*
  1630. +  * This function has been shamelessly adapted from the msdos fs
  1631. +  */
  1632. + static int parse_options (char * options, struct super_block *sb)
  1633. + {
  1634. +     char * this_char;
  1635. +     char * value;
  1636. +     int rc;
  1637. +     
  1638. +     if (!options)
  1639. +         return 0;
  1640. +     while ((this_char = options)) {
  1641. +         if (!strncmp(this_char, "--,", 3))
  1642. +             this_char += 2;
  1643. +         if (*this_char == ',') {
  1644. +             /* An empty option, or the option "--",
  1645. +                introduces options to be passed through to
  1646. +                the subfs */
  1647. +             supermount_debug ("assigning remainder\n");
  1648. +             return copy_option(&sb->u.supermount_sb.s_data,
  1649. +                        ++this_char);
  1650. +         }
  1651. +         if ((options = strchr (this_char, ',')))
  1652. +             *options++ = 0;
  1653. +         
  1654. +         if ((value = strchr (this_char, '=')) != NULL)
  1655. +             *value++ = 0;
  1656. +         supermount_debug ("parsing option \"%s\"\n", this_char);
  1657. +         if (!strcmp (this_char, "fs")) {
  1658. +             rc = copy_option(&sb->u.supermount_sb.s_type, value);
  1659. +             if (rc) return rc;
  1660. +         } else if (!strcmp (this_char, "dev")) {
  1661. +             rc = copy_option(&sb->u.supermount_sb.s_devname, 
  1662. +                      value);
  1663. +             if (rc) return rc;
  1664. +         } else if (!strcmp (this_char, "debug")) {
  1665. +             supermount_debug_enable = 1;
  1666. +         } else {
  1667. +             printk ("supermount: "
  1668. +                 "Unrecognized mount option %s\n", this_char);
  1669. +             return -EINVAL;
  1670. +         }
  1671. +     }
  1672. +     return 0;
  1673. + }
  1674. + /* read_super: the main mount() entry point into the VFS layer. */
  1675. + struct super_block * supermount_read_super (struct super_block * sb, 
  1676. +                         void * data,
  1677. +                         int silent)
  1678. + {
  1679. +     sb->s_blocksize = 1024;
  1680. +     sb->s_blocksize_bits = 10;
  1681. +     sb->s_magic = SUPERMOUNT_SUPER_MAGIC;
  1682. +     sb->s_op = &supermount_sops;
  1683. +     unlock_super(sb);
  1684. +     sb->u.supermount_sb.s_state = SUPERMOUNT_UNMOUNTED;
  1685. +     sb->u.supermount_sb.s_default_mode = 0111 | S_IFDIR;
  1686. +     sb->u.supermount_sb.s_mflags = sb->s_flags & (MS_REMOUNT - 1);
  1687. +     sb->u.supermount_sb.s_data = NULL;
  1688. +     sb->u.supermount_sb.s_undermount = NULL;
  1689. +     sb->u.supermount_sb.s_subfs = NULL;
  1690. +     sb->u.supermount_sb.s_opencount = 0;
  1691. +     sb->u.supermount_sb.s_dirty = 0;
  1692. +     sb->u.supermount_sb.s_type = NULL;
  1693. +     sb->u.supermount_sb.s_devname = NULL;
  1694. +     if (parse_options ((char *) data, sb)) {
  1695. +         sb->s_dev = 0;
  1696. +         return NULL;
  1697. +     }
  1698. +     if (!sb->u.supermount_sb.s_type)
  1699. +         copy_option(&sb->u.supermount_sb.s_type, "msdos");
  1700. +     if (!sb->u.supermount_sb.s_devname)
  1701. +         copy_option(&sb->u.supermount_sb.s_devname, "/dev/fd0");
  1702. +     sb->s_flags = sb->u.supermount_sb.s_mflags;
  1703. +     if (!(sb->s_mounted = iget(sb, SUPERMOUNT_ROOT_INO))) {
  1704. +         sb->s_dev = 0;
  1705. +         supermount_error (sb, "supermount_read_super",
  1706. +                   "get root inode failed\n");
  1707. +         return NULL;
  1708. +     }
  1709. +     return sb;
  1710. + }
  1711. + void supermount_write_super (struct super_block * sb)
  1712. + {
  1713. +     supermount_media_check(sb);
  1714. +     if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1715. +         struct super_block *tmp = sb->u.supermount_sb.s_subfs;
  1716. +         if (tmp && tmp->s_op && tmp->s_op->write_super)
  1717. +             tmp->s_op->write_super(tmp);
  1718. +     }
  1719. +     sb->s_dirt = 0;
  1720. + }
  1721. + #if 0
  1722. + int supermount_remount (struct super_block * sb, int * flags, char * data)
  1723. + {
  1724. + }
  1725. + #endif /* 0 */
  1726. + void supermount_statfs (struct super_block * sb, struct statfs * buf, 
  1727. +             int bufsize)
  1728. + {
  1729. +     unsigned short fs;
  1730. +     struct statfs tmp;
  1731. +     supermount_media_check(sb);
  1732. +     if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1733. +         struct super_block * tmpsb = 
  1734. +             sb->u.supermount_sb.s_undermount->i_mount->i_sb;
  1735. +         fs = get_fs();
  1736. +         set_fs(KERNEL_DS);
  1737. +         if (tmpsb->s_op && tmpsb->s_op->statfs)
  1738. +             tmpsb->s_op->statfs(tmpsb, &tmp, sizeof(tmp));
  1739. +         set_fs(fs);
  1740. +     } else {
  1741. +         tmp.f_bsize = sb->s_blocksize;
  1742. +         tmp.f_blocks = 0;
  1743. +         tmp.f_bfree = 0;
  1744. +         tmp.f_bavail = 0;
  1745. +         tmp.f_files = 0;
  1746. +         tmp.f_ffree = 0;
  1747. +         tmp.f_namelen = 0;
  1748. +     }
  1749. +     tmp.f_type = SUPERMOUNT_SUPER_MAGIC;
  1750. +     memcpy_tofs(buf, &tmp, bufsize);
  1751. + }
  1752. + /* Check for media change, but without invalidating buffers and inodes */
  1753. + static int just_check_disk_change(dev_t dev)
  1754. + {
  1755. +     if (!query_disk_change(dev))
  1756. +         return 0;
  1757. +     supermount_debug("Disk change detected on device %d/%d\n",
  1758. +              MAJOR(dev), MINOR(dev));
  1759. +     return 1;
  1760. + }
  1761. + static void umount_subfs(struct super_block *sb)
  1762. + {
  1763. +     int retval;
  1764. +     struct inode *inode, *subi;
  1765. +     
  1766. +     supermount_debug("Trying to unmount device %s.\n",
  1767. +              sb->u.supermount_sb.s_devname);
  1768. +     
  1769. +     /* Detach the subfs from the supermount root inode */
  1770. +     inode = sb->s_mounted;
  1771. +     /* Inode may not be set if we are currently unmounting the superfs */
  1772. +     if (inode) {
  1773. +         subi = inode->u.supermount_i.i_hidden;
  1774. +         if (subi) {
  1775. +             subi->i_shadow = 0;
  1776. +             inode->u.supermount_i.i_hidden = 0;
  1777. +             iput(inode);
  1778. +         }
  1779. +     }
  1780. +         
  1781. +     if (sb->u.supermount_sb.s_subfs->s_mounted->i_count != 1)
  1782. +         supermount_panic (sb, "umount_subfs",
  1783. +                   "subfs root i_count = %d, should be 1\n",
  1784. +                   sb->u.supermount_sb.s_subfs->s_mounted->i_count);
  1785. +     if (sb->u.supermount_sb.s_undermount->i_count != 1)
  1786. +         supermount_panic (sb, "umount_subfs",
  1787. +                   "undermount i_count = %d, should be 1\n",
  1788. +                   sb->u.supermount_sb.s_subfs->s_mounted->i_count);
  1789. +     sb->u.supermount_sb.s_subfs->s_mounted->i_count++;
  1790. +     sb->u.supermount_sb.s_state = SUPERMOUNT_UNMOUNTED;
  1791. +     retval = do_umounti(sb->u.supermount_sb.s_subfs->s_mounted);
  1792. +     if (retval)
  1793. +         supermount_panic (sb, "umount_subfs",
  1794. +                   "Help - can't umount subfs!!!");
  1795. +     supermount_debug("subfs is unmounted.\n");
  1796. +     sb->u.supermount_sb.s_undermount = 0;
  1797. +     sb->u.supermount_sb.s_version = ++event;
  1798. +     sb->u.supermount_sb.s_subfs = 0;
  1799. +     sb->s_flags = sb->u.supermount_sb.s_mflags;
  1800. +     if (inode)
  1801. +         inode->i_mode = sb->u.supermount_sb.s_default_mode;
  1802. + }
  1803. + /* Return 0 (OK) if medium is valid. */
  1804. + int supermount_media_check(struct super_block * sb) 
  1805. + {
  1806. +     int retval;
  1807. +     unsigned short fs;
  1808. +     /* If there are still files open, we never bother checking the
  1809. +            medium. */
  1810. +     if (sb->u.supermount_sb.s_subfs && 
  1811. +         subfs_is_active(sb)) {
  1812. +         supermount_debug ("subfs is active.\n");
  1813. +         return 0;
  1814. +     }
  1815. +     supermount_debug ("starting (%sactive now)\n",
  1816. +               (sb->u.supermount_sb.s_subfs &&
  1817. +                subfs_is_active(sb)) ?
  1818. +               "" : "not ");
  1819. +     
  1820. +     lock_super(sb);
  1821. +     /* Are we checking for mount or unmount/remount? */
  1822. +     if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1823. +         /* Already mounted --- check for disk change or
  1824. +            disk not present */
  1825. +         int dev = sb->u.supermount_sb.s_subfs->s_dev;
  1826. +         if (!just_check_disk_change(dev)) {
  1827. +             unlock_super(sb);
  1828. +             return 0;
  1829. +         }
  1830. +         
  1831. +         /* We have a disk change!  Unmount the subfs */
  1832. +         supermount_debug ("trying to unmount\n");
  1833. +         umount_subfs(sb);
  1834. +         /* The call to just_check_disk_change may clear the media-
  1835. +            changed flag on the device, so we need to force a media
  1836. +            invalidation.  We don't want to do this before unmounting
  1837. +            the subfs, naturally! */
  1838. +         invalidate_media(dev);
  1839. +         /* Now we are unmounted; fall through to the next check. */
  1840. +     }
  1841. +     
  1842. +     if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1843. +         unlock_super(sb);
  1844. +         return 0;
  1845. +     }
  1846. +     
  1847. +     /* OK, we're unmounted now --- can we remount?  Please? */
  1848. +     if (!sb->u.supermount_sb.s_undermount) {
  1849. +         sb->u.supermount_sb.s_undermount =
  1850. +             iget(sb, SUPERMOUNT_HIDDEN_INO);
  1851. +         if (!sb->u.supermount_sb.s_undermount)
  1852. +             supermount_panic (sb, "supermount_media_check",
  1853. +                       "Can't get root hidden inode!");
  1854. +         sb->u.supermount_sb.s_undermount->i_flags |= S_UNBOUND;
  1855. +     }
  1856. +     sb->u.supermount_sb.s_version = ++event;
  1857. +     sb->s_mounted->u.supermount_i.i_sb_version = event;
  1858. +     supermount_debug ("trying to mount\n");
  1859. +     supermount_debug ("fs=%s, dev=%s, data=%s, flags=%08lx\n",
  1860. +               sb->u.supermount_sb.s_type,
  1861. +               sb->u.supermount_sb.s_devname,
  1862. +               sb->u.supermount_sb.s_data,
  1863. +               sb->s_flags);
  1864. +     fs = get_fs();
  1865. +     set_fs(KERNEL_DS);
  1866. +     sb->s_flags = sb->u.supermount_sb.s_mflags,
  1867. +         retval = do_mounti(sb->u.supermount_sb.s_undermount,
  1868. +                    "<supermount>",
  1869. +                    sb->u.supermount_sb.s_devname,
  1870. +                    sb->u.supermount_sb.s_type,
  1871. +                    sb->s_flags | MS_MGC_VAL,
  1872. +                    sb->u.supermount_sb.s_data);
  1873. +     if (retval == -EROFS && !(sb->u.supermount_sb.s_mflags & MS_RDONLY)) {
  1874. +         /* OK, that failed, so try it readonly */
  1875. +         sb->s_flags |= MS_RDONLY;
  1876. +         retval = do_mounti(sb->u.supermount_sb.s_undermount,
  1877. +                    "<supermount>",
  1878. +                    sb->u.supermount_sb.s_devname,
  1879. +                    sb->u.supermount_sb.s_type,
  1880. +                    sb->s_flags | MS_MGC_VAL,
  1881. +                    sb->u.supermount_sb.s_data);
  1882. +     }
  1883. +     set_fs(fs);
  1884. +     
  1885. +     unlock_super(sb);
  1886. +     if (retval) {
  1887. +         sb->s_flags = sb->u.supermount_sb.s_mflags;
  1888. +         iput(sb->u.supermount_sb.s_undermount);
  1889. +         sb->u.supermount_sb.s_undermount = 0;
  1890. +         supermount_debug ("Mount failed, errno %d\n", -retval);
  1891. +         return 1;
  1892. +     }
  1893. +     /* Hey --- success!!! */
  1894. +     sb->u.supermount_sb.s_subfs = sb->u.supermount_sb.s_undermount
  1895. +         ->i_mount->i_sb;
  1896. +     if (!sb->u.supermount_sb.s_subfs->s_mounted)
  1897. +         supermount_panic (sb, "supermount_media_check", 
  1898. +                   "Mounted subfs has no root inode!");
  1899. +     sb->u.supermount_sb.s_state = SUPERMOUNT_SUSPENDED;
  1900. +     supermount_debug ("Mount succeeded!\n");
  1901. +     /* For counting open inodes on the subfs, we rely on the fact
  1902. +            that the root inode is always exactly one count.  So make
  1903. +            sure we guarantee it is always open! */
  1904. +     supermount_iopen(sb->s_mounted);
  1905. +     sb->s_mounted->i_flags |= S_UNBOUND;
  1906. +     return 0;
  1907. + }
  1908. + /* Check whether an inode still belongs to valid medium. */
  1909. + int supermount_check_inode(struct inode * inode)
  1910. + {
  1911. +     supermount_debug ("inode = %ld\n", inode->i_ino);
  1912. +     
  1913. +     if (supermount_media_check(inode->i_sb))
  1914. +         return 1;
  1915. +     if (inode_is_obsolete(inode)) {
  1916. +         /* What happens if we remount an old disk, and get
  1917. +                    back the same superinode number?  subiget() will
  1918. +                    handle it through the i_subino field, and
  1919. +                    supermount_attach will avoid reusing the old
  1920. +                    inode. */
  1921. +         return 1;
  1922. +     }
  1923. +     return 0;
  1924. + }
  1925. *** linux/include/linux/fs.h.~1~    Thu May 30 15:49:07 1996
  1926. --- linux/include/linux/fs.h    Thu May 30 15:22:31 1996
  1927. ***************
  1928. *** 72,77 ****
  1929. --- 72,81 ----
  1930.   #define S_WRITE        128    /* Write on file/directory/symlink */
  1931.   #define S_APPEND    256    /* Append-only file */
  1932.   #define S_IMMUTABLE    512    /* Immutable file */
  1933. + #define S_UNBOUND    1024    /* inode is not bound to user space,
  1934. +                    and so the filesystem may be
  1935. +                    unmounted even if this inode is in
  1936. +                    use. */
  1937.   
  1938.   /*
  1939.    * Flags that can be altered by MS_REMOUNT
  1940. ***************
  1941. *** 101,106 ****
  1942. --- 105,111 ----
  1943.   #define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE)
  1944.   #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
  1945.   #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
  1946. + #define IS_UNBOUND(inode) ((inode)->i_flags & S_UNBOUND)
  1947.   
  1948.   /* the read-only stuff doesn't really belong here, but any other place is
  1949.      probably as bad and I don't want to create yet another include file. */
  1950. ***************
  1951. *** 214,219 ****
  1952. --- 219,225 ----
  1953.   }
  1954.   
  1955.   #include <linux/pipe_fs_i.h>
  1956. + #include <linux/supermount_fs_i.h>
  1957.   #include <linux/minix_fs_i.h>
  1958.   #include <linux/ext_fs_i.h>
  1959.   #include <linux/ext2_fs_i.h>
  1960. ***************
  1961. *** 282,287 ****
  1962. --- 288,295 ----
  1963.       unsigned long    i_nrpages;
  1964.       struct semaphore i_sem;
  1965.       struct inode_operations *i_op;
  1966. +     struct inode * i_shadow;
  1967. +     struct inode_shadow_operations * i_shadow_op;
  1968.       struct super_block *i_sb;
  1969.       struct wait_queue *i_wait;
  1970.       struct file_lock *i_flock;
  1971. ***************
  1972. *** 303,308 ****
  1973. --- 311,317 ----
  1974.       unsigned short i_writecount;
  1975.       union {
  1976.           struct pipe_inode_info pipe_i;
  1977. +         struct supermount_inode_info supermount_i;
  1978.           struct minix_inode_info minix_i;
  1979.           struct ext_inode_info ext_i;
  1980.           struct ext2_inode_info ext2_i;
  1981. ***************
  1982. *** 400,405 ****
  1983. --- 409,415 ----
  1984.   
  1985.   extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **);
  1986.   
  1987. + #include <linux/supermount_fs_sb.h>
  1988.   #include <linux/minix_fs_sb.h>
  1989.   #include <linux/ext_fs_sb.h>
  1990.   #include <linux/ext2_fs_sb.h>
  1991. ***************
  1992. *** 429,434 ****
  1993. --- 439,445 ----
  1994.       struct inode * s_mounted;
  1995.       struct wait_queue * s_wait;
  1996.       union {
  1997. +         struct supermount_sb_info supermount_sb;
  1998.           struct minix_sb_info minix_sb;
  1999.           struct ext_sb_info ext_sb;
  2000.           struct ext2_sb_info ext2_sb;
  2001. ***************
  2002. *** 489,494 ****
  2003. --- 500,511 ----
  2004.       int (*smap) (struct inode *,int);
  2005.   };
  2006.   
  2007. + struct inode_shadow_operations {
  2008. +     void (*open) (struct inode *, int);
  2009. +     void (*write) (struct inode *);
  2010. +     void (*release) (struct inode *);
  2011. + };
  2012.   struct super_operations {
  2013.       void (*read_inode) (struct inode *);
  2014.       int (*notify_change) (struct inode *, struct iattr *);
  2015. ***************
  2016. *** 598,606 ****
  2017. --- 615,625 ----
  2018.   }
  2019.   
  2020.   extern int check_disk_change(kdev_t dev);
  2021. + extern int query_disk_change(kdev_t dev);
  2022.   extern void invalidate_inodes(kdev_t dev);
  2023.   extern void invalidate_inode_pages(struct inode *);
  2024.   extern void invalidate_buffers(kdev_t dev);
  2025. + extern void invalidate_media(kdev_t dev);
  2026.   extern int floppy_is_wp(int minor);
  2027.   extern void sync_inodes(kdev_t dev);
  2028.   extern void sync_dev(kdev_t dev);
  2029. ***************
  2030. *** 659,664 ****
  2031. --- 678,686 ----
  2032.   
  2033.   extern void show_buffers(void);
  2034.   extern void mount_root(void);
  2035. + extern int do_mounti(struct inode *_inode, const char *, const char *, 
  2036. +              const char *, unsigned long, const void *);
  2037. + extern int do_umounti(struct inode *);
  2038.   
  2039.   #ifdef CONFIG_BLK_DEV_INITRD
  2040.   extern kdev_t real_root_dev;
  2041. *** linux/include/linux/supermount_fs.h.~1~    Thu May 30 15:49:07 1996
  2042. --- linux/include/linux/supermount_fs.h    Thu May 30 15:22:31 1996
  2043. ***************
  2044. *** 0 ****
  2045. --- 1,165 ----
  2046. + /*
  2047. +  *  linux/include/linux/supermount_fs.h
  2048. +  *
  2049. +  *  Defines and strutures for the dynamic remounting of removable media
  2050. +  *
  2051. +  *  Copyright (C) 1995
  2052. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2053. +  *
  2054. +  *  from
  2055. +  *
  2056. +  *  linux/include/linux/minix_fs.h
  2057. +  *  Copyright (C) 1991, 1992  Linus Torvalds
  2058. +  *
  2059. +  *  and
  2060. +  *
  2061. +  *  linux/include/linux/ext2_fs.h
  2062. +  *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  2063. +  */
  2064. + #ifndef _LINUX_SUPERMOUNT_FS_H
  2065. + #define _LINUX_SUPERMOUNT_FS_H
  2066. + #include <linux/types.h>
  2067. + #define SUPERMOUNT_DEBUG
  2068. + #define SUPERMOUNT_VERSION        "0.4"
  2069. + /*
  2070. +  * Debug code
  2071. +  */
  2072. + #ifdef SUPERMOUNT_DEBUG
  2073. +  extern char supermount_debug_enable;
  2074. +  #define supermount_debug(f, a...) \
  2075. +     { \
  2076. +         if (supermount_debug_enable) { \
  2077. +             printk ("SUPERMOUNT DEBUG (%s, %d): %s: ", \
  2078. +                 __FILE__, __LINE__, __FUNCTION__); \
  2079. +             printk (f, ## a); \
  2080. +         } \
  2081. +     }
  2082. + #else
  2083. +  #define supermount_debug(f, a...)    /**/
  2084. + #endif
  2085. + /*
  2086. +  * Special inodes numbers
  2087. +  */
  2088. + #define SUPERMOUNT_HIDDEN_INO         0    /* Hidden inode for
  2089. +                            sub-mounting */
  2090. + #define SUPERMOUNT_ROOT_INO         1    /* Root inode */
  2091. + /*
  2092. +  * The supermount superblock magic number
  2093. +  */
  2094. + #define SUPERMOUNT_SUPER_MAGIC    0x9fa1
  2095. + #ifdef __KERNEL__
  2096. + /*
  2097. +  * Function prototypes
  2098. +  */
  2099. + /*
  2100. +  * Ok, these declarations are also in <linux/kernel.h> but none of the
  2101. +  * supermount source programs needs to include it so they are duplicated here.
  2102. +  */
  2103. + #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
  2104. + # define NORET_TYPE    __volatile__
  2105. + # define ATTRIB_NORET  /**/
  2106. + # define NORET_AND     /**/
  2107. + #else
  2108. + # define NORET_TYPE    /**/
  2109. + # define ATTRIB_NORET  __attribute__((noreturn))
  2110. + # define NORET_AND     noreturn,
  2111. + #endif
  2112. + /* How to test if a supermount filesystem is active or not: */
  2113. + static inline int subfs_is_active(struct super_block *sb)
  2114. + {
  2115. +     /* The subfs is deemed inactive iff only the root is open, and
  2116. +            the its i_count is one.  */
  2117. +     return (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED &&
  2118. +         (sb->u.supermount_sb.s_opencount > 1 ||
  2119. +          sb->u.supermount_sb.s_undermount->i_mount->i_count > 1));
  2120. + }
  2121. + /* How to test if an inode is obsolete: */
  2122. + static inline int inode_is_obsolete(struct inode *inode)
  2123. + {
  2124. +     return (inode->u.supermount_i.i_sb_version !=
  2125. +         inode->i_sb->u.supermount_sb.s_version);
  2126. + }
  2127. + /* Manage the subfs dirty flag */
  2128. + static inline void mark_subfs_dirty(struct super_block *sb)
  2129. + {
  2130. +     sb->u.supermount_sb.s_dirty = 1;
  2131. + }
  2132. + static inline void mark_subfs_clean(struct super_block *sb)
  2133. + {
  2134. +     sb->u.supermount_sb.s_dirty = 0;
  2135. + }
  2136. + static inline int subfs_is_dirty(struct super_block *sb)
  2137. + {
  2138. +     return (sb->u.supermount_sb.s_dirty);
  2139. + }
  2140. + /* inode.c */
  2141. + extern struct inode * subiget(struct inode *);
  2142. + extern void supermount_iopen(struct inode *);
  2143. + extern void supermount_iclose(struct inode *);
  2144. + extern void supermount_go_inactive(struct super_block *);
  2145. + extern struct inode * supermount_attach(struct super_block *, struct inode *);
  2146. + extern void supermount_read_inode (struct inode *);
  2147. + extern void supermount_write_inode (struct inode *);
  2148. + extern void supermount_put_inode (struct inode *);
  2149. + extern int supermount_permission (struct inode *, int mask);
  2150. + /* namei.c */
  2151. + extern void supermount_release (struct inode *, struct file *);
  2152. + extern int supermount_lookup (struct inode *,const char *, int, struct inode **);
  2153. + extern int supermount_create (struct inode *,const char *, int, int,
  2154. +                   struct inode **);
  2155. + extern int supermount_mkdir (struct inode *, const char *, int, int);
  2156. + extern int supermount_rmdir (struct inode *, const char *, int);
  2157. + extern int supermount_unlink (struct inode *, const char *, int);
  2158. + extern int supermount_symlink (struct inode *, const char *, int, const char *);
  2159. + extern int supermount_link (struct inode *, struct inode *, const char *, int);
  2160. + extern int supermount_mknod (struct inode *, const char *, int, int, int);
  2161. + extern int supermount_rename (struct inode *, const char *, int,
  2162. +                   struct inode *, const char *, int);
  2163. + /* super.c */
  2164. + extern void supermount_error (struct super_block *, const char *, const char *, ...)
  2165. +     __attribute__ ((format (printf, 3, 4)));
  2166. + extern NORET_TYPE void supermount_panic (struct super_block *, const char *,
  2167. +                    const char *, ...)
  2168. +     __attribute__ ((NORET_AND format (printf, 3, 4)));
  2169. + extern void supermount_warning (struct super_block *, const char *, const char *, ...)
  2170. +     __attribute__ ((format (printf, 3, 4)));
  2171. + extern void supermount_put_super (struct super_block *);
  2172. + extern void supermount_write_super (struct super_block *);
  2173. + extern int supermount_remount (struct super_block *, int *, char *);
  2174. + extern struct super_block * supermount_read_super (struct super_block *,void *,int);
  2175. + extern void supermount_statfs (struct super_block *, struct statfs *, int);
  2176. + extern int supermount_media_check (struct super_block *);
  2177. + extern int supermount_check_inode (struct inode *);
  2178. + /* dir.c */
  2179. + extern struct inode_operations supermount_dir_iops;
  2180. + extern struct inode_operations supermount_root_iops;
  2181. + /* inode.c */
  2182. + extern struct inode_shadow_operations supermount_shadow_iops;
  2183. + /* file.c */
  2184. + /* extern struct inode_operations supermount_shadow_file_iops; */
  2185. + /* symlink.c */
  2186. + extern struct inode_operations supermount_symlink_iops;
  2187. + #endif    /* __KERNEL__ */
  2188. + #endif    /* _LINUX_SUPERMOUNT_FS_H */
  2189. *** linux/include/linux/supermount_fs_i.h.~1~    Thu May 30 15:49:07 1996
  2190. --- linux/include/linux/supermount_fs_i.h    Thu May 30 15:22:31 1996
  2191. ***************
  2192. *** 0 ****
  2193. --- 1,23 ----
  2194. + /*
  2195. +  *  linux/include/linux/supermount_fs.h
  2196. +  *
  2197. +  *  In-core inode structure for the dynamic remounting of removable media
  2198. +  *
  2199. +  *  Copyright (C) 1995
  2200. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2201. +  *
  2202. +  */
  2203. + #ifndef _LINUX_SUPERMOUNT_FS_I_H
  2204. + #define _LINUX_SUPERMOUNT_FS_I_H
  2205. + struct supermount_inode_info {
  2206. +     struct inode *    i_hidden;
  2207. +     int        i_sb_version;
  2208. +     int        i_subino;
  2209. +     int        i_counted;/* Has this inode been counted in
  2210. +                      the superblock reference counts
  2211. +                      yet? */
  2212. + };
  2213. + #endif    /* _LINUX_SUPERMOUNT_FS_I_H */
  2214. *** linux/include/linux/supermount_fs_sb.h.~1~    Thu May 30 15:49:07 1996
  2215. --- linux/include/linux/supermount_fs_sb.h    Thu May 30 15:22:31 1996
  2216. ***************
  2217. *** 0 ****
  2218. --- 1,44 ----
  2219. + /*
  2220. +  *  linux/include/linux/supermount_sb_fs.h
  2221. +  *
  2222. +  *  In-core superblock struct for the dynamic remounting of removable media
  2223. +  *
  2224. +  *  Copyright (C) 1995
  2225. +  *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2226. +  *
  2227. +  */
  2228. + #ifndef _LINUX_SUPERMOUNT_FS_SB_H
  2229. + #define _LINUX_SUPERMOUNT_FS_SB_H
  2230. + typedef enum {
  2231. +     SUPERMOUNT_UNMOUNTED,    /* No media mounted */
  2232. +     SUPERMOUNT_SUSPENDED,    /* Mounted but suspended because 
  2233. +                    no files open */
  2234. +     SUPERMOUNT_ONLINE,    /* Mounted and active */
  2235. + } sm_state_t;
  2236. + /*
  2237. +  * supermount super-block data in memory
  2238. +  */
  2239. + struct supermount_sb_info {
  2240. +     sm_state_t    s_state;
  2241. +     int        s_version;    /* Used to indicate obsolete inodes */
  2242. +     mode_t        s_default_mode;    /* Default mode for supermount root */
  2243. +     const char *    s_type;        /* Type of fs to be sub-mounted */
  2244. +     const char *    s_devname;    /* Where to mount the subfs */
  2245. +     int        s_mflags;    /* Flags to pass when mounting subfs */
  2246. +     const char *    s_data;        /* Data to pass when mounting subfs */
  2247. +     struct inode *    s_undermount;    /* Mount point for subfs */
  2248. +     struct super_block * s_subfs;    /* The submounted fs sb */
  2249. +     int        s_opencount;    /* Refcount of opened inodes
  2250. +                        (an inode in use as cwd
  2251. +                        does not count as open) */
  2252. +     
  2253. +     /* Flags */
  2254. +     int        s_dirty : 1;    /* Do we need to fsync() the subfs? */
  2255. + };
  2256. + #endif    /* _LINUX_SUPERMOUNT_FS_SB_H */
  2257.